package com.wjk.cms.controller;

import com.alibaba.fastjson.JSONObject;

import com.wjk.cms.pojo.*;
import com.wjk.cms.util.DateUtil;
import com.wjk.cms.util.MD5Util;
import com.wjk.cms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author WUGN
 * @des
 * @date 2021/9/13 16:50
 */
@Controller
@Slf4j
public class WxCallbackController {

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CardService cardService;



    /**
     * 微信支付成功之后的回调方法
     */
    @Transactional
    @RequestMapping({"/auth/pay/notify/wx", "/auth/pay/notify/wechat"})
    @ResponseBody
    public String payCallBack(HttpServletRequest request) {
        String resXml = getPayNotifyWxResponseText();
        try {
            Document doc = readXmlDocFromRequest(request);
            log.info("微信支付成功回调\n" + doc.asXML());
            Map<String, String> map = parseXmlToMap(doc);
            if ("SUCCESS".equals(map.get("result_code"))) {

                JSONObject attachJson = JSONObject.parseObject(map.get("attach"));
                String user_id = attachJson.getString("user_id");
                User user = userService.findById(Long.parseLong(user_id));
                if (user == null) {
                    log.error("微信支付成功回调发生错误: 找不到用户 - code:" + user.getId());
                    return resXml;
                }


                onStoreOrderPaid(attachJson,user);

                return resXml;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信支付成功回调处理遇到异常 - " + e.getMessage(), e);
        }
        return resXml;
    }





    private void onStoreOrderPaid(JSONObject orderData,User user) {
        Order order = new Order();
        order.setCode(orderData.getString("order_code"));
        order.setUserId(orderData.getLong("user_id"));
        order.setAmount(orderData.getString("amount1"));
        order.setAmount2(orderData.getString("amount2"));
        order.setCardId(orderData.getLong("card_id"));
        order.setStatus(1);
        orderService.save(order);
        Card card = cardService.getById(order.getCardId());
        if(card!=null){
            card.setActiveTime(new Date());
            card.setStatus(2);
            cardService.save(card);
        }else{
            log.error("卡不存在："+order.getCardId());
        }



    }



    private Map<String, String> parseXmlToMap(Document doc) {
        Map<String, String> map = new HashMap<>();
        Element rootElt = doc.getRootElement();
        map.put("result_code", rootElt.elementText("result_code")); // 业务结果
        map.put("attach", rootElt.elementText("attach")); // 业务结果
        map.put("total_fee", rootElt.elementText("total_fee"));
        map.put("transaction_id", rootElt.elementText("transaction_id"));
        map.put("out_trade_no", rootElt.elementText("out_trade_no"));
        map.put("openid", rootElt.elementText("openid"));
        return map;
    }

    private Document readXmlDocFromRequest(HttpServletRequest request) throws IOException, DocumentException {
        SAXReader reader = new SAXReader();
        reader.setEncoding("UTF-8");
        return reader.read(request.getInputStream());
    }

    private Document readXmlDocFromString(String xml) throws UnsupportedEncodingException, DocumentException {
        SAXReader reader = new SAXReader();
        reader.setEncoding("UTF-8");
        return reader.read(new ByteArrayInputStream(xml.getBytes("UTF-8")));
    }

    private String getPayNotifyWxResponseText() {
        return "<xml>"
                + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>"
                + "</xml>";
    }

    private static String decryptData(String base64Data, String password) throws Exception {
        // 创建密码器
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
        // 使用密钥初始化，设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
        // 执行操作
        byte[] result = cipher.doFinal(Base64.decodeBase64(base64Data));
        return new String(result, "UTF-8");
    }

    private static SecretKeySpec getSecretKey(String password) {
        SecretKeySpec key = new SecretKeySpec(MD5Util.encode(password, "UTF-8").toLowerCase().getBytes(), "AES");
        return key;
    }

}

